package com.icejoywoo.rss;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.cordova.api.PluginResult;
import org.apache.cordova.api.PluginResult.Status;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.Log;
import android.widget.Toast;

import com.phonegap.api.Plugin;

/**
 * A simple phonegap plugin to RSS reader 
 * include 3 actions
 * @author icejoywoo
 *
 */
public class RssHelperPlugin extends Plugin {
	
	// actions name defination 
	public static final String GET_URL_CONTENT_ACTION = "get_url_content";
	public static final String OPEN_URL_IN_BROWSER_ACTION = "open_url_in_browser";
	public static final String TOAST = "toast";
	
	@Override
	public PluginResult execute(String action, JSONArray data, String callbackId) {
		log("Plugin Called, action -> " + action + ", data -> " + data);
		PluginResult result = null;
		if (GET_URL_CONTENT_ACTION.equals(action)) {
			try {
				String url = data.getString(0);
				int index = data.getInt(1);
				String content = getUrlContent(url);
				log("Got the url content: " + content);
				JSONObject resultData = new JSONObject();
				resultData.put("data", content);
				resultData.put("index", index);
				result = new PluginResult(Status.OK, resultData);
			} catch (JSONException e) {
				error("Got JSON Exception " + e.getMessage()); 
				result = new PluginResult(Status.JSON_EXCEPTION, e.getMessage());
			} catch (MalformedURLException e) {
				error("Got malformed URL Exception " + e.getMessage()); 
				result = new PluginResult(Status.MALFORMED_URL_EXCEPTION, e.getMessage());
			} catch (IOException e) {
				error("Got IO Exception " + e.getMessage()); 
				result = new PluginResult(Status.IO_EXCEPTION, e.getMessage());
			}
		} else if (OPEN_URL_IN_BROWSER_ACTION.equals(action)) {
			try {
				// 获取url
				String url = data.getString(0);
				// 开启系统自带浏览器
//				Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
//				browserIntent.setClassName("com.android.browser","com.android.browser.BrowserActivity");
//				browserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//				this.ctx.startActivity(browserIntent);
				((Vibrator) this.ctx.getSystemService(Service.VIBRATOR_SERVICE)).vibrate(200);
				// 使用自定义的browser
				Intent intent = new Intent();
				Bundle bundle = new Bundle();
				bundle.putString("url", url);
				intent.putExtras(bundle);
				intent.setClass(this.ctx.getContext(), SimpleBrowser.class);
				this.ctx.startActivity(intent);
				result = new PluginResult(Status.OK, "Start Browser Activity Successfully.");
			} catch (JSONException e) {
				error("Got JSON Exception " + e.getMessage()); 
				result = new PluginResult(Status.JSON_EXCEPTION, e.getMessage());
			}
		} else if (TOAST.equals(action)) {
			try {
				// 获取message
				String msg = data.getString(0);
				this.ctx.runOnUiThread(new RunnableToast(msg, Toast.LENGTH_SHORT));
				result = new PluginResult(Status.OK, "Start Browser Activity Successfully.");
			} catch (JSONException e) {
				error("Got JSON Exception " + e.getMessage()); 
				result = new PluginResult(Status.JSON_EXCEPTION, e.getMessage());
			}
		}
		return result;
	}
	
	/**
	 * Just a simple log wrapper for this class
	 * @param msg the log message
	 */
	private void log(String msg) {
		Log.d("RssHelperPlugin", msg);
	}
	
	/**
	 * Just a simple log wrapper for this class
	 * @param msg the log message
	 */
	private void error(String msg) {
		Log.e("RssHelperPlugin", msg);
	}
	
	/**
	 * Get the content of given url
	 * @param urlString given url string
	 * @param sourceCharset the content's charset
	 * @return the content of given url
	 * @throws IOException
	 */
	private String getUrlContent(String urlString) throws IOException {
		StringBuffer content = new StringBuffer();
		BufferedReader reader = null;
		HttpURLConnection conn = null;
		String sourceCharset = null;
		try {
			URL url = new URL(urlString);
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestProperty("Content-type", "text/html;charset=utf-8");
			conn.connect();
			
			// 判断字符编码
			// 1.根据content-type判断
			Map<String, List<String>> headers = conn.getHeaderFields();
			String type = headers.get("Content-Type").get(0);
			if (-1 != type.indexOf("charset")) {
				sourceCharset = type.substring(type.indexOf("charset") + 8);
				log("header: " + sourceCharset + ", url: " + urlString);
			}  
			
			// 2. 根据xml文件的coding来判断, 需要获取两次输入流
			if (sourceCharset == null) {
				reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				String line = reader.readLine();
				if (-1 != line.indexOf("encoding")) {
					sourceCharset = line.substring(line.indexOf("encoding") + 10, line.indexOf("?>") - 1).trim();
					log("encoding: " + sourceCharset + ", url: " + urlString);
				}
				// 重新载入url连接, 会造成性能问题
				if (reader != null) {
					conn.disconnect();
					conn = (HttpURLConnection) url.openConnection();
					conn.connect();
				}
			}
			
			// 3. 当上述方法无法获取编码时, 默认使用utf-8
			if (sourceCharset == null) {
				// 默认字符编码utf8
				sourceCharset = "utf-8";
			}
			
			log("parse-code: " + sourceCharset + ", url: " + urlString);
			
			reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), sourceCharset));
			String line = null;
			while ((line = reader.readLine()) != null) {
				content.append(line);
			}
		} finally {
			// 关闭资源
			if (reader != null)
				reader.close();
			if (conn != null)
				conn.disconnect();
		}
		return content.toString();
	}
	
	/**
	 *  toast for phonegap plugin
	 * @author icejoywoo
	 *
	 */
	class RunnableToast implements Runnable {
		private String message;
		private int length;

		public RunnableToast(String message, int length) {
			this.message = message;
			this.length = length;
		}

		@Override
		public void run() {
			Toast.makeText(ctx.getContext(), message, length).show();
		}

	}
}
